<template>
  <div class="min-h-screen bg-gray-50 py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-4xl mx-auto">
      <!-- 页面标题和说明 -->
      <div class="text-center mb-8">
        <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-gray-900 mb-2">学生照片批量上传</h1>
        <p class="text-gray-600 max-w-2xl mx-auto">
          上传包含学生照片的文件夹，系统将根据文件名自动匹配学生信息并更新照片路径。
          <br class="hidden sm:inline">建议照片文件名为学生学号，支持JPG、PNG等常见图片格式。
        </p>
      </div>

      <!-- 主卡片容器 -->
      <el-card class="overflow-hidden shadow-lg transition-all duration-300 hover:shadow-xl border-0 rounded-xl">
        <!-- 上传区域 -->
        <div
            class="upload-area relative border-2 border-dashed border-gray-300 rounded-lg p-10 text-center transition-all duration-300 hover:border-primary/70 hover:bg-primary/5 cursor-pointer"
            @click="selectFolder"
            @dragover.prevent="isDragging = true"
            @dragleave.prevent="isDragging = false"
            @drop.prevent="handleDrop; isDragging = false"
            :class="{ 'border-primary bg-primary/10': isDragging }"
        >
          <!-- 上传图标和文字 -->
          <div class="upload-icon mb-4 text-5xl text-primary/80">
            <i class="el-icon-folder-opened"></i>
          </div>

          <h3 class="text-lg font-medium text-gray-900 mb-2">点击或拖拽文件夹到此处</h3>
          <p class="text-gray-500 mb-4 text-sm">支持所有常见图片格式，文件夹大小建议不超过100MB</p>

          <!-- 上传示例 -->
          <div class="mt-6 bg-white/80 rounded-lg p-3 shadow-sm inline-block">
            <p class="text-xs text-gray-500 flex items-center">
              <i class="el-icon-info-circle text-primary mr-1"></i>
              示例：文件夹中包含 2023001.jpg、2023002.png 等以学号命名的图片
            </p>
          </div>

          <!-- 隐藏的文件输入 -->
          <input
              type="file"
              ref="folderInput"
              webkitdirectory
              directory
              class="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
              @change="handleFolderSelect"
          >
        </div>

        <!-- 文件列表区域 -->
        <div v-if="fileList.length > 0" class="mt-6 px-1">
          <div class="flex justify-between items-center mb-3">
            <h3 class="font-medium text-gray-800">
              待上传文件 <span class="text-sm font-normal text-gray-500 ml-2">({{ fileList.length }}个文件)</span>
            </h3>
            <el-button
                type="text"
                size="small"
                class="text-gray-500 hover:text-danger"
                @click="clearFiles"
            >
              清空列表
            </el-button>
          </div>

          <el-table
              :data="fileList"
              border
              stripe
              class="rounded-lg overflow-hidden"
              height="300"
          >
            <el-table-column prop="name" label="文件名" width="350"></el-table-column>
            <el-table-column prop="size" label="大小" width="120">
              <template #default="scope">{{ formatSize(scope.row.size) }}</template>
            </el-table-column>
            <el-table-column prop="type" label="类型" width="100">
              <template #default="scope">
                {{ scope.row.type.split('/')[1].toUpperCase() || 'UNKNOWN' }}
              </template>
            </el-table-column>
            <el-table-column label="状态" width="140">
              <template #default="scope">
                <el-tag
                    :type="statusConfig[scope.row.status].type"
                    effect="light"
                >
                  <i :class="statusConfig[scope.row.status].icon" class="mr-1"></i>
                  {{ statusConfig[scope.row.status].text }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <!-- 操作按钮区域 -->
        <div
            v-if="fileList.length > 0"
            class="mt-6 flex flex-wrap gap-3 justify-center"
        >
          <el-button
              type="primary"
              size="default"
              :loading="isUploading"
              :disabled="isUploading"
              @click="startUpload"
              class="px-6"
          >
            <i class="el-icon-upload mr-2"></i> 开始上传
          </el-button>

          <el-button
              type="default"
              size="default"
              :disabled="isUploading"
              @click="clearFiles"
          >
            <i class="el-icon-refresh-left mr-2"></i> 重新选择
          </el-button>
        </div>

        <!-- 上传进度条 -->
        <div v-if="uploadProgress > 0 && uploadProgress < 100" class="mt-6 px-4">
          <div class="flex justify-between mb-1">
            <span class="text-sm text-gray-600">上传进度</span>
            <span class="text-sm font-medium text-primary">{{ uploadProgress }}%</span>
          </div>
          <el-progress
              :percentage="uploadProgress"
              stroke-width="6"
              stroke-linecap="round"
              :status="uploadProgress === 100 ? 'success' : ''"
          ></el-progress>
        </div>

        <!-- 上传结果提示 -->
        <div v-if="uploadResult.msg" class="mt-6 px-4">
          <el-alert
              :title="uploadResult.msg"
              :type="uploadResult.success ? 'success' : 'error'"
              closable
              @close="uploadResult.msg = ''"
              class="transition-all duration-300"
          ></el-alert>
        </div>

        <!-- 上传完成后的匹配结果 -->
        <div v-if="matchResult.visible" class="mt-6 px-4 pb-4">
          <el-card
              :bordered="false"
              class="bg-gray-50"
          >
            <div slot="header" class="flex items-center text-gray-800">
              <i class="el-icon-check-circle text-success mr-2"></i>
              <span>照片匹配结果</span>
            </div>
            <div class="pt-2">
              <p class="text-gray-700">
                共处理 <span class="font-medium text-primary">{{ matchResult.totalCount }}</span> 个文件
              </p>
              <p class="text-gray-700 mt-1">
                成功匹配 <span class="font-medium text-success">{{ matchResult.matchedCount }}</span> 名学生
              </p>
              <p class="text-gray-700 mt-1" v-if="matchResult.unmatchedCount > 0">
                未匹配 <span class="font-medium text-warning">{{ matchResult.unmatchedCount }}</span> 个文件
              </p>
            </div>
          </el-card>
        </div>
      </el-card>

      <!-- 帮助信息 -->
      <div class="mt-8 bg-white rounded-lg shadow-sm p-5 border border-gray-100">
        <h3 class="font-medium text-gray-800 mb-3 flex items-center">
          <i class="el-icon-question-circle text-primary mr-2"></i>
          使用帮助
        </h3>
        <ul class="text-gray-600 text-sm space-y-2">
          <li class="flex items-start">
            <i class="el-icon-circle-check text-success mt-1 mr-2 text-xs"></i>
            <span>请确保照片文件名为学生的唯一标识符（如学号），不含特殊字符</span>
          </li>
          <li class="flex items-start">
            <i class="el-icon-circle-check text-success mt-1 mr-2 text-xs"></i>
            <span>支持的图片格式：JPG、PNG、GIF、BMP等常见格式</span>
          </li>
          <li class="flex items-start">
            <i class="el-icon-circle-check text-success mt-1 mr-2 text-xs"></i>
            <span>建议单张照片大小不超过5MB，以保证上传速度</span>
          </li>
          <li class="flex items-start">
            <i class="el-icon-circle-check text-success mt-1 mr-2 text-xs"></i>
            <span>上传完成后系统会自动进行匹配，匹配结果将显示在页面上</span>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { uploadStudentPhotos, matchStudentPhotos } from '@/api/student/studentPhotos.js'

// 引用
const folderInput = ref(null)

// 状态变量
const fileList = ref([])
const uploadProgress = ref(0)
const isUploading = ref(false)
const isDragging = ref(false)

// 上传结果
const uploadResult = reactive({
  msg: '',
  success: false
})

// 匹配结果
const matchResult = reactive({
  visible: false,
  totalCount: 0,
  matchedCount: 0,
  unmatchedCount: 0
})

// 状态配置
const statusConfig = {
  waiting: { text: '等待上传', type: 'info', icon: 'el-icon-clock' },
  uploading: { text: '上传中', type: 'warning', icon: 'el-icon-loading' },
  success: { text: '上传成功', type: 'success', icon: 'el-icon-check' },
  error: { text: '上传失败', type: 'danger', icon: 'el-icon-error' }
}

// 选择文件夹
const selectFolder = () => {
  folderInput.value.click()
}

// 处理文件夹选择
const handleFolderSelect = (e) => {
  const files = e.target.files
  if (files.length > 0) {
    fileList.value = Array.from(files)
        .map(file => ({
          name: file.name,
          size: file.size,
          type: file.type,
          file: file,
          status: 'waiting'
        }))
        .filter(item => item.type.startsWith('image/'))

    if (fileList.value.length === 0) {
      ElMessage.warning('所选文件夹中未找到图片文件，请选择包含图片的文件夹')
    } else {
      ElMessage.success(`成功识别 ${fileList.value.length} 个图片文件`)
    }
  }
  // 清空input值，否则同一文件夹无法重复选择
  e.target.value = ''
}

// 处理拖拽
const handleDrop = (e) => {
  const items = e.dataTransfer.items
  if (items) {
    for (let i = 0; i < items.length; i++) {
      if (items[i].kind === 'file') {
        const entry = items[i].webkitGetAsEntry()
        if (entry.isDirectory) {
          readDirectory(entry)
        }
      }
    }
  }
}

// 读取文件夹内容
const readDirectory = (entry) => {
  const reader = entry.createReader()
  reader.readEntries(entries => {
    entries.forEach(entry => {
      if (entry.isFile) {
        entry.file(file => {
          if (file.type.startsWith('image/')) {
            fileList.value.push({
              name: file.name,
              size: file.size,
              type: file.type,
              file: file,
              status: 'waiting'
            })
          }
        })
      } else if (entry.isDirectory) {
        readDirectory(entry)
      }
    })
  })
}

// 格式化文件大小
const formatSize = (size) => {
  if (size < 1024) {
    return size + ' B'
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + ' KB'
  } else {
    return (size / (1024 * 1024)).toFixed(2) + ' MB'
  }
}

// 开始上传
const startUpload = () => {
  if (fileList.value.length === 0) {
    ElMessage.warning('请先选择包含图片的文件夹')
    return
  }

  uploadProgress.value = 0
  uploadResult.msg = ''
  uploadResult.success = false
  isUploading.value = true

  // 创建FormData
  const formData = new FormData()
  fileList.value.forEach((item, index) => {
    formData.append('files', item.file, item.name)
    fileList.value[index].status = 'uploading'
  })

  // 上传文件
  uploadStudentPhotos(formData, progress => {
    uploadProgress.value = Math.round(progress * 100)
  }).then(response => {
    if (response.code === 200) {
      uploadResult.msg = '文件上传成功，正在进行学生匹配...'
      uploadResult.success = true
      // 上传成功后进行匹配
      matchPhotos()
    } else {
      fileList.value.forEach(item => {
        item.status = 'error'
      })
      uploadResult.msg = '上传失败: ' + (response.msg || '未知错误')
      uploadResult.success = false
      isUploading.value = false
    }
  }).catch(error => {
    fileList.value.forEach(item => {
      item.status = 'error'
    })
    uploadResult.msg = '上传出错: ' + (error.message || '网络错误')
    uploadResult.success = false
    isUploading.value = false
  })
}

// 匹配学生照片
const matchPhotos = () => {
  matchStudentPhotos().then(response => {
    if (response.code === 200) {
      fileList.value.forEach(item => {
        item.status = 'success'
      })
      uploadProgress.value = 100
      uploadResult.msg = '所有文件上传完成！'

      // 显示匹配结果
      matchResult.visible = true
      matchResult.totalCount = response.data.totalCount
      matchResult.matchedCount = response.data.matchedCount
      matchResult.unmatchedCount = response.data.totalCount - response.data.matchedCount
    } else {
      uploadResult.msg = '匹配失败: ' + (response.msg || '未知错误')
      uploadResult.success = false
    }
    isUploading.value = false
  }).catch(error => {
    uploadResult.msg = '匹配出错: ' + (error.message || '网络错误')
    uploadResult.success = false
    isUploading.value = false
  })
}

// 清空文件列表
const clearFiles = () => {
  if (isUploading.value) {
    ElMessage.warning('正在上传中，无法清空列表')
    return
  }

  fileList.value = []
  uploadProgress.value = 0
  uploadResult.msg = ''
  matchResult.visible = false
}
</script>

<style scoped>
.upload-area {
  margin: 20px;
}

.upload-icon {
  transition: transform 0.3s ease;
}

.upload-area:hover .upload-icon {
  transform: scale(1.05);
}

::v-deep .el-progress__bar {
  border-radius: 3px;
}

::v-deep .el-alert {
  border-radius: 6px;
}

::v-deep .el-table th {
  background-color: #f9fafb;
}
</style>
